#ifndef LOG_ELEM_H
#define LOG_ELEM_H

#include <stdio.h>
#include <glib.h>

typedef enum {
    LEP_PID,
    LEP_FILE,
    LEP_PORT,
    LEP_UID,
    LEP_RES // 其他资源，如注册表表项、程序名
} LogElemPointType;

typedef enum {
    /* 文件操作 */
    LE_READ,
    LE_WRITE,
    LE_DELETE,
    LE_CREATE,
    /* 网络操作 */
    LE_SEND,
    LE_RECV,
    /* 进程操作 */
    LE_FORK,
    LE_EXEC,
    LE_IPC,
    /* 鉴权操作 */
    LE_LOGIN,
    LE_INIT,
    /* 关联操作 */
    LE_REFER,
} LogElemType;

typedef struct LogElem{
    LogElemType type;
    LogElemPointType src_type;
    gchar *src;
    LogElemPointType dest_type;
    gchar *dest;
    GPtrArray *extra; // 附加信息，如程序名，NULL为无附加信息
    GStringChunk *str_pool;
} LogElem;

int creat_log_elem (LogElem **le);

int free_log_elem (LogElem *le);

int clean_log_elem (LogElem *le);

int log_elem_populate (LogElem *le, LogElemType type, LogElemPointType src_type, const char * src, LogElemPointType dest_type, const char *dest);

int log_elem_add_extra (LogElem *le, const char *extra);

static void inline
print_log_elem_point_type (LogElemPointType type) {
    switch (type)
    {
    case LEP_PID:
        printf ("(pid)");
        break;
    case LEP_FILE:
        printf ("(file)");
        break;
    case LEP_PORT:
        printf ("(port)");
        break;
    case LEP_UID:
        printf ("(uid)");
        break;
    case LEP_RES:
        printf ("(resource)");
        break;
    default:
        break;
    }
}

static void inline
print_log_elem_type (LogElemType type) {
    switch (type)
    {
    case LE_READ:
        printf ("read");
        break;
    case LE_WRITE:
        printf ("write");
        break;
    case LE_DELETE:
        printf ("delete");
        break;
    case LE_CREATE:
        printf ("create");
        break;
    case LE_SEND:
        printf ("send");
        break;
    case LE_RECV:
        printf ("recv");
        break;
    case LE_FORK:
        printf ("fork");
        break;
    case LE_EXEC:
        printf ("exec");
        break;
    case LE_IPC:
        printf ("ipc");
        break;
    case LE_LOGIN:
        printf ("login");
        break;
    case LE_INIT:
        printf ("init");
        break;
    case LE_REFER:
        printf ("refer");
        break;
    default:
        break;
    }
}
#endif